#include "../source/sylar.h"

void run_in_fiber2()
{
    LOG(DEBUG, "run_in_fiber2 begin");
    LOG(DEBUG, "run_in_fiber2 end");
}

void run_in_fiber()
{
    LOG(DEBUG, "run_in_fiber begin");

    LOG(DEBUG, "before run_in_fiber yield");
    Fiber::GetThis()->yield();
    LOG(DEBUG, "aftre run_in_fiber yield");

    LOG(DEBUG, "run_in_fiber end");
}

void test_fiber()
{
    LOG(DEBUG, "test_fiber begin");

    Fiber::GetThis();
    Fiber::ptr fiber(new Fiber(run_in_fiber, 0, false));
    LOG(DEBUG, "use_count: %d", fiber.use_count()); // 1

    LOG(DEBUG, "before test_fiber resume");
    fiber->resume();
    LOG(DEBUG, "after test_fiber resume");

    /**
     * 关于fiber智能指针的引用计数为3的说明：
     * 一份在当前函数的fiber指针，一份在MainFunc的cur指针
     * 还有一份在在run_in_fiber的GetThis()结果的临时变量里
     */
    LOG(DEBUG, "use_count: %d", fiber.use_count());    // 3
    LOG(DEBUG, "fiber status: %d", fiber->getState()); // READY

    LOG(DEBUG, "before test_fiber resume again");
    fiber->resume();
    LOG(DEBUG, "after test_fiber resume again");

    LOG(DEBUG, "use_count: %d", fiber.use_count());    // 1
    LOG(DEBUG, "fiber status: %d", fiber->getState()); // TERM

    // 上一个协程结束之后,复用其栈空间再创建一个新的协程
    fiber->reset(run_in_fiber2);
    fiber->resume();

    LOG(DEBUG, "use_count: %d", fiber.use_count()); // 1

    LOG(DEBUG, "test_fiber end");
}

int main(int argc, char *argv[])
{
    SetThreadName("main_thread");

    LOG(DEBUG, "main begin");

    std::vector<Thread::ptr> threads;
    for (int i = 0; i < 2; i++)
    {
        threads.push_back(Thread::ptr(new Thread(&test_fiber, "thread_" + std::to_string(i))));
    }

    for (auto thread : threads)
    {
        thread->join();
    }

    LOG(DEBUG, "main end");
    return 0;
}